home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / usenet / volume8 / tinymud / part04 < prev   
Encoding:
Internet Message Format  |  1989-12-31  |  33.5 KB

  1. Path: uunet!wyse!mips!zaphod.mps.ohio-state.edu!usc!cs.utexas.edu!rice!uw-beaver!zephyr.ens.tek.com!tekred!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v08i083:  tinymud - user-extendible multi-user adventure game, Part04/04
  5. Message-ID: <5098@tekred.CNA.TEK.COM>
  6. Date: 20 Jan 90 03:16:12 GMT
  7. Sender: nobody@tekred.CNA.TEK.COM
  8. Lines: 1261
  9. Approved: billr@saab.CNA.TEK.COM
  10.  
  11. Submitted-by: DEEJ@MAINE.BITNET
  12. Posting-number: Volume 8, Issue 83
  13. Archive-name: tinymud/Part04
  14.  
  15.  
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then unpack
  19. # it by saving it into a file and typing "sh file".  To overwrite existing
  20. # files, type "sh file -c".  You can also feed this as standard input via
  21. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  22. # will see the following message at the end:
  23. #        "End of archive 4 (of 4)."
  24. # Contents:  Makefile config.h copyright.h dump.c help.c help.txt
  25. #   match.h paths.c player.c predicates.c restart-cmu sanity-check.c
  26. #   small.db.README stringutil.c utils.c
  27. # Wrapped by billr@saab on Fri Jan 19 19:14:31 1990
  28. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  29. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  30.   echo shar: Will not clobber existing file \"'Makefile'\"
  31. else
  32. echo shar: Extracting \"'Makefile'\" \(3022 characters\)
  33. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  34. X#
  35. X# Whatever you put in for $(CC) must be able to grok ANSI C.
  36. X#
  37. XCC=gcc
  38. XOPTIM= -O -g -pipe -W -Wreturn-type -Wunused -Wcomment -Wwrite-strings
  39. X# 
  40. X# To log failed commands (HUH's) to stderr, include -DLOG_FAILED_COMMANDS
  41. X# To restricted object-creating commands to users with the BUILDER bit,
  42. X#   include -DRESTRICTED_BUILDING
  43. X# To log all commands, include -DLOG_COMMANDS
  44. X#
  45. XDEFS= -DLOG_FAILED_COMMANDS
  46. XCFLAGS= $(OPTIM) $(DEFS)
  47. X
  48. X# Everything except interface.c --- allows for multiple interfaces
  49. XCFILES= create.c game.c help.c look.c match.c move.c player.c predicates.c \
  50. X    rob.c set.c speech.c stringutil.c utils.c wiz.c db.c game.c 
  51. X
  52. X# .o versions of above
  53. XOFILES= create.o game.o help.o look.o match.o move.o player.o predicates.o \
  54. X    rob.o set.o speech.o stringutil.o utils.o wiz.o db.o 
  55. X
  56. X# Files in the standard distribution
  57. XDISTFILES= $(CFILES) config.h db.h externs.h interface.h match.h \
  58. X    interface.c dump.c sanity-check.c extract.c paths.c \
  59. X    help.txt small.db minimal.db restart-cmu README small.db.README \
  60. X    Makefile copyright.h
  61. X
  62. XDESTDIR= /usr/asp/tinymud
  63. X
  64. XOUTFILES= netmud dump paths sanity-check extract TAGS
  65. X
  66. Xall: extract sanity-check dump paths netmud TAGS
  67. X
  68. XTAGS: *.c *.h
  69. X    etags *.c *.h
  70. X
  71. Xnetmud: interface.o $(OFILES)
  72. X    -mv -f netmud netmud~
  73. X    $(CC) $(CFLAGS) -o netmud interface.o $(OFILES)
  74. X
  75. Xdump: dump.o utils.o db.o
  76. X    -rm -f dump
  77. X    $(CC) $(CFLAGS) -o dump dump.o utils.o db.o
  78. X
  79. Xsanity-check: sanity-check.o utils.o db.o
  80. X    -rm -f sanity-check
  81. X    $(CC) $(CFLAGS) -o sanity-check sanity-check.o utils.o db.o
  82. X
  83. Xextract: extract.o utils.o db.o
  84. X    -rm -f extract
  85. X    $(CC) $(CFLAGS) -o extract extract.o utils.o db.o
  86. X
  87. Xpaths: paths.o db.o
  88. X    -rm -f paths
  89. X    $(CC) $(CFLAGS) -o paths paths.o db.o
  90. X
  91. Xclean:
  92. X    -rm -f *.o a.out core gmon.out $(OUTFILES)
  93. X
  94. Xdist.tar.Z: $(DISTFILES)
  95. X    tar cvf - $(DISTFILES) | compress -c > dist.tar.Z.NEW
  96. X    mv dist.tar.Z.NEW dist.tar.Z
  97. X
  98. X# DO NOT REMOVE THIS LINE OR CHANGE ANYTHING AFTER IT #
  99. Xcreate.o: create.c db.h config.h interface.h externs.h
  100. Xdb.o: db.c db.h
  101. Xdump.o: dump.c db.h
  102. Xextract.o: extract.c db.h
  103. Xfix.o: fix.c db.h config.h
  104. Xgame.o: game.c db.h config.h interface.h match.h externs.h
  105. Xhelp.o: help.c db.h config.h interface.h externs.h
  106. Xinterface.o: interface.c db.h interface.h config.h
  107. Xjanitor.o: janitor.c db.h config.h interface.h externs.h
  108. Xlook.o: look.c db.h config.h interface.h match.h externs.h
  109. Xmatch.o: match.c db.h config.h match.h
  110. Xmove.o: move.c db.h config.h interface.h match.h externs.h
  111. Xold.o: old.c
  112. Xpaths.o: paths.c db.h config.h
  113. Xplayer.o: player.c db.h config.h interface.h externs.h
  114. Xpredicates.o: predicates.c db.h interface.h config.h externs.h
  115. Xrob.o: rob.c db.h config.h interface.h match.h externs.h
  116. Xsanity-check.o: sanity-check.c db.h config.h
  117. Xset.o: set.c db.h config.h match.h interface.h externs.h
  118. Xspeech.o: speech.c db.h interface.h match.h config.h externs.h
  119. Xstringutil.o: stringutil.c externs.h
  120. Xtestmain.o: testmain.c db.h interface.h
  121. Xutils.o: utils.c db.h
  122. Xwiz.o: wiz.c db.h interface.h match.h externs.h
  123. Xconfig.h:
  124. Xdb.h:
  125. Xexterns.h: db.h
  126. Xinterface.h: db.h
  127. Xmatch.h: db.h
  128. END_OF_FILE
  129. if test 3022 -ne `wc -c <'Makefile'`; then
  130.     echo shar: \"'Makefile'\" unpacked with wrong size!
  131. fi
  132. # end of 'Makefile'
  133. fi
  134. if test -f 'config.h' -a "${1}" != "-c" ; then 
  135.   echo shar: Will not clobber existing file \"'config.h'\"
  136. else
  137. echo shar: Extracting \"'config.h'\" \(1981 characters\)
  138. sed "s/^X//" >'config.h' <<'END_OF_FILE'
  139. X#include "copyright.h"
  140. X
  141. X/* room number of player start location */
  142. X#define PLAYER_START 0
  143. X
  144. X/* minimum cost to create various things */
  145. X#define OBJECT_COST 10
  146. X#define EXIT_COST 1
  147. X#define LINK_COST 1
  148. X#define ROOM_COST 10
  149. X
  150. X/* cost to do a scan */
  151. X#define LOOKUP_COST 1
  152. X
  153. X/* magic cookies */
  154. X#define NOT_TOKEN '!'
  155. X#define LOOKUP_TOKEN '*'
  156. X#define NUMBER_TOKEN '#'
  157. X
  158. X/* magic command cookies */
  159. X#define SAY_TOKEN '"'
  160. X#define POSE_TOKEN ':'
  161. X
  162. X/* amount of object endowment, based on cost */
  163. X#define MAX_OBJECT_ENDOWMENT 100
  164. X#define OBJECT_ENDOWMENT(cost) (((cost)-5)/5)
  165. X
  166. X/* amount at which temple stops being so profitable */
  167. X#define MAX_PENNIES 10000
  168. X
  169. X/* penny generation parameters */
  170. X#define PENNY_RATE 10        /* 1/chance of getting a penny per room */
  171. X
  172. X/* costs of kill command */
  173. X#define KILL_BASE_COST 100    /* prob = expenditure/KILL_BASE_COST */
  174. X#define KILL_MIN_COST 10
  175. X#define KILL_BONUS 50        /* paid to victim */
  176. X
  177. X/* delimeter for lists of exit aliases */
  178. X#define EXIT_DELIMITER ';'
  179. X
  180. X/* timing stuff */
  181. X#define DUMP_INTERVAL 3600    /* seconds between dumps */
  182. X#define COMMAND_TIME_MSEC 250    /* time slice length in milliseconds */
  183. X#define COMMAND_BURST_SIZE 250    /* commands allowed per user in a burst */
  184. X#define COMMANDS_PER_TIME 1    /* commands per time slice after burst */
  185. X
  186. X/* maximum amount of queued output */
  187. X#define MAX_OUTPUT 16384
  188. X
  189. X#define TINYPORT 4201
  190. X#define WELCOME_MESSAGE "Welcome to TinyMUD\nTo connect to your existing character, enter \"connect name password\"\nTo create a new character, enter \"create name password\"\nUse the news command to get up-to-date news on program changes.\n\nYou can disconnect using the QUIT command, which must be capitalized as shown.\n\nUse the WHO command to find out who is currently active.\n\n"
  191. X
  192. X#define LEAVE_MESSAGE "\n***Disconnected***\n"
  193. X
  194. X#define QUIT_COMMAND "QUIT"
  195. X#define WHO_COMMAND "WHO"
  196. X#define PREFIX_COMMAND "OUTPUTPREFIX"
  197. X#define SUFFIX_COMMAND "OUTPUTSUFFIX"
  198. X
  199. X#define HELP_FILE "help.txt"
  200. X
  201. X#define NEWS_FILE "news.txt"
  202. END_OF_FILE
  203. if test 1981 -ne `wc -c <'config.h'`; then
  204.     echo shar: \"'config.h'\" unpacked with wrong size!
  205. fi
  206. # end of 'config.h'
  207. fi
  208. if test -f 'copyright.h' -a "${1}" != "-c" ; then 
  209.   echo shar: Will not clobber existing file \"'copyright.h'\"
  210. else
  211. echo shar: Extracting \"'copyright.h'\" \(1391 characters\)
  212. sed "s/^X//" >'copyright.h' <<'END_OF_FILE'
  213. X/* -*-C-*-
  214. X
  215. XCopyright (c) 1989 by David Applegate, James Aspnes, and Bennet Yee.
  216. X
  217. XThis material was developed by the above-mentioned authors.
  218. XPermission to copy this software, to redistribute it, and to use it
  219. Xfor any purpose is granted, subject to the following restrictions and
  220. Xunderstandings.
  221. X
  222. X1. Any copy made of this software must include this copyright notice
  223. Xin full.
  224. X
  225. X2. Users of this software agree to make their best efforts (a) to
  226. Xreturn to the above-mentioned authors any improvements or extensions
  227. Xthat they make, so that these may be included in future releases; and
  228. X(b) to inform the authors of noteworthy uses of this software.
  229. X
  230. X3. All materials developed as a consequence of the use of this
  231. Xsoftware shall duly acknowledge such use, in accordance with the usual
  232. Xstandards of acknowledging credit in academic research.
  233. X
  234. X4. The authors have made no warrantee or representation that the
  235. Xoperation of this software will be error-free, and the authors are
  236. Xunder no obligation to provide any services, by way of maintenance,
  237. Xupdate, or otherwise.
  238. X
  239. X5. In conjunction with products arising from the use of this material,
  240. Xthere shall be no use of the names of the authors, of Carnegie-Mellon
  241. XUniversity, nor of any adaptation thereof in any advertising,
  242. Xpromotional, or sales literature without prior written consent from
  243. Xthe authors and Carnegie-Mellon University in each case. */
  244. X
  245. END_OF_FILE
  246. if test 1391 -ne `wc -c <'copyright.h'`; then
  247.     echo shar: \"'copyright.h'\" unpacked with wrong size!
  248. fi
  249. # end of 'copyright.h'
  250. fi
  251. if test -f 'dump.c' -a "${1}" != "-c" ; then 
  252.   echo shar: Will not clobber existing file \"'dump.c'\"
  253. else
  254. echo shar: Extracting \"'dump.c'\" \(2923 characters\)
  255. sed "s/^X//" >'dump.c' <<'END_OF_FILE'
  256. X#include "copyright.h"
  257. X
  258. X#include <stdio.h>
  259. X
  260. X#include "db.h"
  261. X
  262. Xvoid main(int argc, char **argv)
  263. X{
  264. X    struct object *o;
  265. X    dbref owner;
  266. X    dbref thing;
  267. X
  268. X    if(argc < 1) {
  269. X    fprintf(stderr, "Usage: %s [owner]\n", *argv);
  270. X    exit(1);
  271. X    }
  272. X    
  273. X    if(argc >= 2) {
  274. X    owner = atol(argv[1]);
  275. X    } else {
  276. X    owner = NOTHING;
  277. X    }
  278. X
  279. X    if(db_read(stdin) < 0) {
  280. X    fprintf(stderr, "%s: bad input\n", argv[0]);
  281. X    exit(5);
  282. X    }
  283. X
  284. X    for(o = db; o < db+db_top; o++) {
  285. X    /* don't show exits separately */
  286. X    if((o->flags & TYPE_MASK) == TYPE_EXIT) continue;
  287. X
  288. X    /* don't show it if it isn't owned by the right player */
  289. X    if(owner != NOTHING && o->owner != owner) continue;
  290. X
  291. X    printf("#%d: %s [%s] at %s(%d) Pennies: %d Type: ",
  292. X           o - db, o->name, db[o->owner].name,
  293. X           getname(o->location),
  294. X           o->location,
  295. X           o->pennies);
  296. X    switch(o->flags & TYPE_MASK) {
  297. X      case TYPE_ROOM:
  298. X        printf("Room");
  299. X        break;
  300. X      case TYPE_EXIT:
  301. X        printf("Exit");
  302. X        break;
  303. X      case TYPE_THING:
  304. X        printf("Thing");
  305. X        break;
  306. X      case TYPE_PLAYER:
  307. X        printf("Player");
  308. X        break;
  309. X      default:
  310. X        printf("***UNKNOWN TYPE***");
  311. X        break;
  312. X    }
  313. X
  314. X    /* handle flags */
  315. X    putchar(' ');
  316. X    if(o->flags & ~TYPE_MASK) {
  317. X        printf("Flags: ");
  318. X        if(o->flags & LINK_OK) printf("LINK_OK ");
  319. X        if(o->flags & DARK) printf("DARK ");
  320. X        if(o->flags & STICKY) printf("STICKY ");
  321. X        if(o->flags & WIZARD) printf("WIZARD ");
  322. X        if(o->flags & TEMPLE) printf("TEMPLE ");
  323. X#ifdef RESTRICTED_BUILDING
  324. X        if(o->flags & BUILDER) printf("BUILDER ");
  325. X#endif /* RESTRICTED_BUILDING */
  326. X    }
  327. X    putchar('\n');
  328. X           
  329. X    if(o->key != NOTHING) printf("KEY: %c%s\n",
  330. X                     o->flags & ANTILOCK ? '!' : ' ',
  331. X                     getname(o->key));
  332. X    if(o->description) {
  333. X        puts("Description:");
  334. X        puts(o->description);
  335. X    }
  336. X    if(o->succ_message) {
  337. X        puts("Success Message:");
  338. X        puts(o->succ_message);
  339. X    }
  340. X    if(o->fail_message) {
  341. X        puts("Fail Message:");
  342. X        puts(o->fail_message);
  343. X    }
  344. X    if(o->ofail) {
  345. X        puts("Other Fail Message:");
  346. X        puts(o->ofail);
  347. X    }
  348. X    if(o->osuccess) {
  349. X        puts("Other Success Message:");
  350. X        puts(o->osuccess);
  351. X    }
  352. X    if(o->contents != NOTHING) {
  353. X        puts("Contents:");
  354. X        DOLIST(thing, o->contents) {
  355. X        /* dump thing description */
  356. X        printf(" %s(%d)\n", db[thing].name, thing);
  357. X        }
  358. X    }
  359. X    if(o->exits != NOTHING) {
  360. X        if((o->flags & TYPE_MASK) == TYPE_ROOM) {
  361. X        puts("Exits:");
  362. X        DOLIST(thing, o->exits) {
  363. X            printf(" %s", getname(thing));
  364. X            if(db[thing].key != NOTHING) {
  365. X            printf(" KEY: %c%s(%d)",
  366. X                   db[thing].flags & ANTILOCK ? '!' : ' ',
  367. X                   getname(db[thing].key),
  368. X                   db[thing].key);
  369. X            }
  370. X            if(db[thing].location != NOTHING) {
  371. X            printf(" => %s(%d)\n",
  372. X                   getname(db[thing].location),
  373. X                   db[thing].location);
  374. X            } else {
  375. X            puts(" ***OPEN***");
  376. X            }
  377. X        }
  378. X        } else {
  379. X        printf("Home: %s(%d)\n", getname(o->exits), o->exits);
  380. X        }
  381. X    }
  382. X    putchar('\n');
  383. X    }
  384. X
  385. X    exit(0);
  386. X}
  387. END_OF_FILE
  388. if test 2923 -ne `wc -c <'dump.c'`; then
  389.     echo shar: \"'dump.c'\" unpacked with wrong size!
  390. fi
  391. # end of 'dump.c'
  392. fi
  393. if test -f 'help.c' -a "${1}" != "-c" ; then 
  394.   echo shar: Will not clobber existing file \"'help.c'\"
  395. else
  396. echo shar: Extracting \"'help.c'\" \(745 characters\)
  397. sed "s/^X//" >'help.c' <<'END_OF_FILE'
  398. X#include "copyright.h"
  399. X
  400. X/* commands for giving help */
  401. X
  402. X#include "db.h"
  403. X#include "config.h"
  404. X#include "interface.h"
  405. X#include "externs.h"
  406. X
  407. Xvoid spit_file(dbref player, const char *filename)
  408. X{
  409. X    FILE *f;
  410. X    char buf[BUFFER_LEN];
  411. X    char *p;
  412. X
  413. X    if((f = fopen(filename, "r")) == NULL) {
  414. X    sprintf(buf, "Sorry, %s is broken.  Management has been notified.",
  415. X        filename);
  416. X    notify(player, buf);
  417. X    fputs("spit_file:", stderr);
  418. X    perror(filename);
  419. X    } else {
  420. X    while(fgets(buf, sizeof buf, f)) {
  421. X        for(p = buf; *p; p++) if(*p == '\n') {
  422. X        *p = '\0';
  423. X        break;
  424. X        }
  425. X        notify(player, buf);
  426. X    }
  427. X    fclose(f);
  428. X    }
  429. X}
  430. X
  431. Xvoid do_help(dbref player)
  432. X{
  433. X    spit_file(player, HELP_FILE);
  434. X}
  435. X
  436. Xvoid do_news(dbref player)
  437. X{
  438. X    spit_file(player, NEWS_FILE);
  439. X}
  440. X
  441. END_OF_FILE
  442. if test 745 -ne `wc -c <'help.c'`; then
  443.     echo shar: \"'help.c'\" unpacked with wrong size!
  444. fi
  445. # end of 'help.c'
  446. fi
  447. if test -f 'help.txt' -a "${1}" != "-c" ; then 
  448.   echo shar: Will not clobber existing file \"'help.txt'\"
  449. else
  450. echo shar: Extracting \"'help.txt'\" \(976 characters\)
  451. sed "s/^X//" >'help.txt' <<'END_OF_FILE'
  452. XThis is TinyMUD version 1.3, a user-extendible, multi-user adventure game.
  453. XBasic commands: 
  454. X move/go <direction>
  455. X get/take <thing>; drop/throw <thing>
  456. X look; look <thing>; look <direction>
  457. X say <message>
  458. X rob <player>; give <player> = <number of pennies>; kill <player>
  459. X inventory
  460. X help
  461. X news
  462. X @describe me = <description>
  463. X @password <oldpassword>=<newpassword>
  464. X page <player> --- tell player that you are looking for them (cost 1 penny)
  465. X gripe <message> --- Complain to the management.
  466. X home --- go home
  467. XOther commands are available for extending the universe.  Many of
  468. Xthese commands cost pennies, which you can obtain in a number of ways.
  469. XFull names of exits can be used in place of a go or move command.  The
  470. Xnames "me" and "here" are special; me means the current player, and
  471. Xhere means the current player's location.
  472. XMore information is available in the reference section of the Library,
  473. Xnorth of the Temple.
  474. XRemember, no matter how bad it gets, you can always go home.
  475. END_OF_FILE
  476. if test 976 -ne `wc -c <'help.txt'`; then
  477.     echo shar: \"'help.txt'\" unpacked with wrong size!
  478. fi
  479. # end of 'help.txt'
  480. fi
  481. if test -f 'match.h' -a "${1}" != "-c" ; then 
  482.   echo shar: Will not clobber existing file \"'match.h'\"
  483. else
  484. echo shar: Extracting \"'match.h'\" \(1359 characters\)
  485. sed "s/^X//" >'match.h' <<'END_OF_FILE'
  486. X#include "copyright.h"
  487. X
  488. X#include "db.h"
  489. X
  490. X/* match functions */
  491. X/* Usage: init_match(player, name, type); match_this(); match_that(); ... */
  492. X/* Then get value from match_result() */
  493. X
  494. X/* initialize matcher */
  495. Xextern void init_match(dbref player, const char *name, int type);
  496. Xextern void init_match_check_keys(dbref player, const char *name, int type);
  497. X
  498. X/* match (LOOKUP_TOKEN)player */
  499. Xextern void match_player(void);
  500. X
  501. X/* match (NUMBER_TOKEN)number */
  502. Xextern void match_absolute(void);
  503. X
  504. X/* match "me" */
  505. Xextern void match_me(void);
  506. X
  507. X/* match "here" */
  508. Xextern void match_here(void);
  509. X
  510. X/* match something player is carrying */
  511. Xextern void match_possession(void);
  512. X
  513. X/* match something in the same room as player */
  514. Xextern void match_neighbor(void);
  515. X
  516. X/* match an exit from player's room */
  517. Xextern void match_exit(void);
  518. X
  519. X/* all of the above, except only Wizards do match_absolute and match_player */
  520. Xextern void match_everything(void);
  521. X
  522. X/* return match results */
  523. Xextern dbref match_result(void); /* returns AMBIGUOUS for multiple inexacts */
  524. Xextern dbref last_match_result(void); /* returns last result */
  525. X
  526. X#define NOMATCH_MESSAGE "I don't see that here."
  527. X#define AMBIGUOUS_MESSAGE "I don't know which one you mean!"
  528. X
  529. Xextern dbref noisy_match_result(void); /* wrapper for match_result */
  530. X                /* noisily notifies player */
  531. X                /* returns matched object or NOTHING */
  532. END_OF_FILE
  533. if test 1359 -ne `wc -c <'match.h'`; then
  534.     echo shar: \"'match.h'\" unpacked with wrong size!
  535. fi
  536. # end of 'match.h'
  537. fi
  538. if test -f 'paths.c' -a "${1}" != "-c" ; then 
  539.   echo shar: Will not clobber existing file \"'paths.c'\"
  540. else
  541. echo shar: Extracting \"'paths.c'\" \(3573 characters\)
  542. sed "s/^X//" >'paths.c' <<'END_OF_FILE'
  543. X#include "copyright.h"
  544. X
  545. X#include <stdio.h>
  546. X
  547. X#include "db.h"
  548. X#include "config.h"
  549. X
  550. X/* Compute shortest path to each room */
  551. X/* Locks cost extra */
  552. X#define INFINITY 2148575    /* MAXINT or thereabouts */
  553. X#define LOCK_COST 10000        /* extra cost for a lock */
  554. X
  555. X/* This code blasts a lot of fields in the database, so */
  556. X/* you don't ever want to write it back out afterwards. */
  557. X
  558. X/* Where things get stored: */
  559. X/* cost to get here gets put in pennies */
  560. X/* location is the previous room that gets you here */
  561. X/* next is the next room in the search queue */
  562. X/* key non-zero means already queued */
  563. X/* contents is previous exit that gets you here */
  564. X
  565. X/* this should be a priority queue, but we're cheap */
  566. Xdbref search_queue_head = NOTHING;
  567. Xdbref search_queue_tail = NOTHING;
  568. X
  569. Xvoid queue_room(dbref room)
  570. X{
  571. X    if(db[room].key) return;
  572. X
  573. X    if(search_queue_tail == NOTHING) {
  574. X    search_queue_head = room;
  575. X    } else {
  576. X    db[search_queue_tail].next = room;
  577. X    }
  578. X    search_queue_tail = room;
  579. X    db[room].next = NOTHING;
  580. X    db[room].key = 1;
  581. X}
  582. X
  583. Xdbref dequeue_room()
  584. X{
  585. X    dbref room;
  586. X
  587. X    if((room = search_queue_head) == NOTHING) return NOTHING;
  588. X    if((search_queue_head = db[room].next) == NOTHING) {
  589. X    search_queue_tail = NOTHING;
  590. X    }
  591. X    db[room].next = NOTHING;
  592. X    db[room].key = 0;
  593. X
  594. X    return room;
  595. X}
  596. X
  597. Xvoid find_paths()
  598. X{
  599. X    dbref room;
  600. X    dbref exit;
  601. X    dbref mycost;        /* dbref[room].pennies */
  602. X    dbref cost;            /* mycost + cost to use exit */
  603. X    dbref dest;            /* exit destination */
  604. X
  605. X    while((room = dequeue_room()) != NOTHING) {
  606. X    /* get first one */
  607. X
  608. X    /* check its exits */
  609. X    mycost = db[room].pennies;
  610. X    DOLIST(exit, db[room].exits) {
  611. X        if((dest = db[exit].location) < 0) continue;
  612. X        cost = mycost + 1;
  613. X        if(db[exit].key != NOTHING) {
  614. X        if(!(db[exit].flags & ANTILOCK)
  615. X           && Typeof(db[exit].key) != TYPE_THING) {
  616. X            continue;    /* we can't get it */
  617. X        } else {
  618. X            cost += LOCK_COST;
  619. X        }
  620. X        }
  621. X        if(cost < db[dest].pennies) {
  622. X        /* it's cheaper, set and queue it */
  623. X        db[dest].pennies = cost;
  624. X        db[dest].location = room;
  625. X        db[dest].contents = exit;
  626. X        queue_room(dest);
  627. X        }
  628. X    }
  629. X    }
  630. X}
  631. X
  632. Xvoid compute_paths(dbref start)
  633. X{
  634. X    dbref room;
  635. X
  636. X    /* clear out all fields we use */
  637. X    for(room = 0; room < db_top; room++) {
  638. X    if(Typeof(room) == TYPE_ROOM) {
  639. X        db[room].location = db[room].next = db[room].contents = NOTHING;
  640. X        db[room].pennies = INFINITY;
  641. X        db[room].key = 0;
  642. X    }
  643. X    }
  644. X
  645. X    /* set up start */
  646. X    db[start].pennies = 0;
  647. X    queue_room(start);
  648. X
  649. X    find_paths();
  650. X}
  651. X
  652. Xvoid print_path(dbref room)
  653. X{
  654. X    dbref prev;
  655. X    dbref exit;
  656. X    dbref key;
  657. X
  658. X    if((prev = db[room].location) != NOTHING) {
  659. X    print_path(prev);
  660. X    exit = db[room].contents;
  661. X    if((key = db[exit].key) != NOTHING) {
  662. X        printf("LOCKED[%s(%d)] ", db[key].name, key);
  663. X    }
  664. X    printf("%s => %s\n", db[exit].name, db[room].name);
  665. X    } 
  666. X}    
  667. X
  668. Xvoid print_paths()
  669. X{
  670. X    dbref room;
  671. X
  672. X    for(room = 0; room < db_top; room++) {
  673. X    if(Typeof(room) == TYPE_ROOM) {
  674. X        printf("%s(%d)[%s]: ",
  675. X           db[room].name, room, db[db[room].owner].name);
  676. X        if(db[room].pennies == INFINITY) {
  677. X        puts("UNREACHABLE");
  678. X        } else {
  679. X        printf("%d + %d locks\n",
  680. X               db[room].pennies % LOCK_COST,
  681. X               db[room].pennies / LOCK_COST);
  682. X        }
  683. X        print_path(room);
  684. X        putchar('\n');
  685. X    }
  686. X    }
  687. X}
  688. X
  689. Xvoid main(int argc, char **argv)
  690. X{
  691. X    dbref start = 0;
  692. X
  693. X    if(argc >= 2) {
  694. X    start = atol(argv[2]);
  695. X    } else {
  696. X    start = PLAYER_START;
  697. X    }
  698. X
  699. X    if(db_read(stdin) < 0) {
  700. X    fprintf(stderr, "%s: bad input\n", argv[0]);
  701. X    exit(5);
  702. X    }
  703. X
  704. X    compute_paths(start);
  705. X    print_paths();
  706. X
  707. X    exit(0);
  708. X}
  709. END_OF_FILE
  710. if test 3573 -ne `wc -c <'paths.c'`; then
  711.     echo shar: \"'paths.c'\" unpacked with wrong size!
  712. fi
  713. # end of 'paths.c'
  714. fi
  715. if test -f 'player.c' -a "${1}" != "-c" ; then 
  716.   echo shar: Will not clobber existing file \"'player.c'\"
  717. else
  718. echo shar: Extracting \"'player.c'\" \(1556 characters\)
  719. sed "s/^X//" >'player.c' <<'END_OF_FILE'
  720. X#include "copyright.h"
  721. X
  722. X#include "db.h"
  723. X#include "config.h"
  724. X#include "interface.h"
  725. X#include "externs.h"
  726. X
  727. X/* don't use this, it's expensive */
  728. X/* maybe soon we'll put in a hash table */
  729. Xdbref lookup_player(const char *name)
  730. X{
  731. X    dbref i;
  732. X
  733. X    for(i = 0; i < db_top; i++) {
  734. X    if(Typeof(i) == TYPE_PLAYER
  735. X       && db[i].name && !string_compare(db[i].name, name)) return i;
  736. X    }
  737. X    return NOTHING;
  738. X}
  739. X
  740. Xdbref connect_player(const char *name, const char *password)
  741. X{
  742. X    dbref player;
  743. X
  744. X    if((player = lookup_player(name)) == NOTHING) return NOTHING;
  745. X    if(db[player].password
  746. X       && *db[player].password
  747. X       &&strcmp(db[player].password, password)) return NOTHING;
  748. X
  749. X    return player;
  750. X}
  751. X
  752. Xdbref create_player(const char *name, const char *password)
  753. X{
  754. X    dbref player;
  755. X
  756. X    if(!ok_player_name(name)) return NOTHING;
  757. X
  758. X    /* else he doesn't already exist, create him */
  759. X    player = new_object();
  760. X
  761. X    /* initialize everything */
  762. X    db[player].name = alloc_string(name);
  763. X    db[player].location = PLAYER_START;
  764. X    db[player].exits = PLAYER_START;    /* home */
  765. X    db[player].owner = player;
  766. X    db[player].flags = TYPE_PLAYER;
  767. X    db[player].password = alloc_string(password);
  768. X    
  769. X    /* link him to PLAYER_START */
  770. X    PUSH(player, db[PLAYER_START].contents);
  771. X
  772. X    return player;
  773. X}
  774. X
  775. Xvoid do_password(dbref player, const char *old, const char *newobj)
  776. X{
  777. X    if(strcmp(old, db[player].password)) {
  778. X    notify(player, "Sorry");
  779. X    } else {
  780. X    free(db[player].password);
  781. X    db[player].password = alloc_string(newobj);
  782. X    notify(player, "Password changed.");
  783. X    }
  784. X}
  785. END_OF_FILE
  786. if test 1556 -ne `wc -c <'player.c'`; then
  787.     echo shar: \"'player.c'\" unpacked with wrong size!
  788. fi
  789. # end of 'player.c'
  790. fi
  791. if test -f 'predicates.c' -a "${1}" != "-c" ; then 
  792.   echo shar: Will not clobber existing file \"'predicates.c'\"
  793. else
  794. echo shar: Extracting \"'predicates.c'\" \(2814 characters\)
  795. sed "s/^X//" >'predicates.c' <<'END_OF_FILE'
  796. X#include "copyright.h"
  797. X
  798. X/* Predicates for testing various conditions */
  799. X
  800. X#include <ctype.h>
  801. X
  802. X#include "db.h"
  803. X#include "interface.h"
  804. X#include "config.h"
  805. X#include "externs.h"
  806. X
  807. Xint can_link_to(dbref who, dbref where)
  808. X{
  809. X    return(where >= 0
  810. X       && where < db_top
  811. X       && Typeof(where) == TYPE_ROOM
  812. X       && (controls(who, where) || (db[where].flags & LINK_OK)));
  813. X}
  814. X
  815. Xint could_doit(dbref player, dbref thing)
  816. X{
  817. X    dbref key;
  818. X    int status;
  819. X
  820. X    if(Typeof(thing) != TYPE_ROOM && db[thing].location == NOTHING) return 0;
  821. X    if((key = db[thing].key) == NOTHING) return 1;
  822. X    status = (player == key || member(key, db[player].contents));
  823. X    return((db[thing].flags & ANTILOCK) ? !status : status);
  824. X}
  825. X
  826. Xint can_doit(dbref player, dbref thing, const char *default_fail_msg)
  827. X{
  828. X    dbref loc;
  829. X    char buf[BUFFER_LEN];
  830. X
  831. X    if((loc = getloc(player)) == NOTHING) return 0;
  832. X
  833. X    if(!could_doit(player, thing)) {
  834. X    /* can't do it */
  835. X    if(db[thing].fail_message) {
  836. X        notify(player, db[thing].fail_message);
  837. X    } else if(default_fail_msg) {
  838. X        notify(player, default_fail_msg);
  839. X    }
  840. X    
  841. X    if(db[thing].ofail) {
  842. X        sprintf(buf, "%s %s", db[player].name, db[thing].ofail);
  843. X        notify_except(db[loc].contents, player, buf);
  844. X    }
  845. X
  846. X    return 0;
  847. X    } else {
  848. X    /* can do it */
  849. X    if(db[thing].succ_message) {
  850. X        notify(player, db[thing].succ_message);
  851. X    }
  852. X
  853. X    if(db[thing].osuccess) {
  854. X        sprintf(buf, "%s %s", db[player].name, db[thing].osuccess);
  855. X        notify_except(db[loc].contents, player, buf);
  856. X    }
  857. X
  858. X    return 1;
  859. X    }
  860. X}
  861. X
  862. Xint can_see(dbref player, dbref thing, int can_see_loc)
  863. X{
  864. X    if(player == thing || Typeof(thing) == TYPE_EXIT) {
  865. X    return 0;
  866. X    } else if(can_see_loc) {
  867. X    return(!Dark(thing) || controls(player, thing));
  868. X    } else {
  869. X    /* can't see loc */
  870. X    return(controls(player, thing));
  871. X    }
  872. X}
  873. X
  874. Xint controls(dbref who, dbref what)
  875. X{
  876. X    /* Wizard controls everything */
  877. X    /* owners control their stuff */
  878. X    return(what >= 0
  879. X       && what < db_top
  880. X       && (Wizard(who)
  881. X           || who == db[what].owner));
  882. X}
  883. X
  884. Xint can_link(dbref who, dbref what)
  885. X{
  886. X    return((Typeof(what) == TYPE_EXIT && db[what].location == NOTHING)
  887. X       || controls(who, what));
  888. X}
  889. X
  890. Xint payfor(dbref who, int cost)
  891. X{
  892. X    if(Wizard(who)) {
  893. X    return 1;
  894. X    } else if(db[who].pennies >= cost) {
  895. X    db[who].pennies -= cost;
  896. X    return 1;
  897. X    } else {
  898. X    return 0;
  899. X    }
  900. X}
  901. X
  902. Xint ok_name(const char *name)
  903. X{
  904. X    return (name
  905. X        && *name
  906. X        && *name != LOOKUP_TOKEN
  907. X        && *name != NUMBER_TOKEN
  908. X        && string_compare(name, "me")
  909. X        && string_compare(name, "home")
  910. X        && string_compare(name, "here"));
  911. X}
  912. X
  913. Xint ok_player_name(const char *name)
  914. X{
  915. X    const char *scan;
  916. X
  917. X    if(!ok_name(name)) return 0;
  918. X
  919. X    for(scan = name; *scan; scan++) {
  920. X    if(!isgraph(*scan)) {
  921. X        return 0;
  922. X    }
  923. X    }
  924. X
  925. X    /* lookup name to avoid conflicts */
  926. X    return (lookup_player(name) == NOTHING);
  927. X}
  928. END_OF_FILE
  929. if test 2814 -ne `wc -c <'predicates.c'`; then
  930.     echo shar: \"'predicates.c'\" unpacked with wrong size!
  931. fi
  932. # end of 'predicates.c'
  933. fi
  934. if test -f 'restart-cmu' -a "${1}" != "-c" ; then 
  935.   echo shar: Will not clobber existing file \"'restart-cmu'\"
  936. else
  937. echo shar: Extracting \"'restart-cmu'\" \(217 characters\)
  938. sed "s/^X//" >'restart-cmu' <<'END_OF_FILE'
  939. X#!/bin/csh -f
  940. Xmv cmu.db cmu.db.old
  941. Xif(-r cmu.db.new) then
  942. X    mv cmu.db.new cmu.db
  943. Xelse
  944. X    cp cmu.db.old cmu.db
  945. Xendif
  946. X
  947. Xcp netmud netmud.running
  948. Xecho RESTARTED AT `date` >> cmu.log
  949. Xexec netmud cmu.db cmu.db.new >>& cmu.log
  950. END_OF_FILE
  951. if test 217 -ne `wc -c <'restart-cmu'`; then
  952.     echo shar: \"'restart-cmu'\" unpacked with wrong size!
  953. fi
  954. chmod +x 'restart-cmu'
  955. # end of 'restart-cmu'
  956. fi
  957. if test -f 'sanity-check.c' -a "${1}" != "-c" ; then 
  958.   echo shar: Will not clobber existing file \"'sanity-check.c'\"
  959. else
  960. echo shar: Extracting \"'sanity-check.c'\" \(2547 characters\)
  961. sed "s/^X//" >'sanity-check.c' <<'END_OF_FILE'
  962. X#include "copyright.h"
  963. X
  964. X#include <stdio.h>
  965. X
  966. X#include "db.h"
  967. X#include "config.h"
  968. X
  969. Xvoid check_exits(dbref i)
  970. X{
  971. X    dbref exit;
  972. X    int count;
  973. X
  974. X    count = 10000;
  975. X    for(exit = db[i].exits;
  976. X    exit != NOTHING;
  977. X    exit = db[exit].next) {
  978. X    if(exit < 0 || exit >= db_top || Typeof(exit) != TYPE_EXIT) {
  979. X        printf("%d has bad exit %d\n", i, exit);
  980. X        break;
  981. X    }
  982. X
  983. X    /* set type of exit to be really strange */
  984. X    db[exit].flags = 4;    /* nonexistent type */
  985. X
  986. X    if(count-- < 0) {
  987. X        printf("%d has looping exits\n");
  988. X        break;
  989. X    }
  990. X    }
  991. X}
  992. X
  993. Xvoid check_contents(dbref i)
  994. X{
  995. X    dbref thing;
  996. X    dbref loc;
  997. X    int count;
  998. X
  999. X    count = 10000;
  1000. X    for(thing = db[i].contents;
  1001. X    thing != NOTHING;
  1002. X    thing = db[thing].next) {
  1003. X    if(thing < 0 || thing >= db_top || Typeof(thing) == TYPE_ROOM) {
  1004. X        printf("%d contains bad object %d\n", i, thing);
  1005. X        break;
  1006. X    } else if((loc = db[thing].location) != i) {
  1007. X        printf("%d in %d but location is %d\n", thing, i, loc);
  1008. X    } else if(Typeof(thing) == TYPE_EXIT) {
  1009. X        db[thing].flags = 4; /* nonexistent type */
  1010. X    }
  1011. X    if(count-- < 0) {
  1012. X        printf("%d has looping contents\n");
  1013. X        break;
  1014. X    }
  1015. X    }
  1016. X}
  1017. X
  1018. Xvoid check_location(dbref i)
  1019. X{
  1020. X    dbref loc;
  1021. X
  1022. X    loc = db[i].location;
  1023. X    if(loc < 0 || loc >= db_top) {
  1024. X    printf("%d has bad loc %d\n", i, loc);
  1025. X    } else if(!member(i, db[loc].contents)) {
  1026. X    printf("%d not in loc %d\n", i, loc);
  1027. X    }
  1028. X}
  1029. X
  1030. Xvoid check_pennies(dbref i)
  1031. X{
  1032. X    dbref pennies;
  1033. X
  1034. X    pennies = db[i].pennies;
  1035. X
  1036. X    switch(Typeof(i)) {
  1037. X      case TYPE_ROOM:
  1038. X      case TYPE_EXIT:
  1039. X    break;
  1040. X      case TYPE_PLAYER:
  1041. X    if(pennies < 0 || pennies > MAX_PENNIES+100) {
  1042. X        printf("Player %s(%d) has %d pennies\n", db[i].name, i, pennies);
  1043. X    }
  1044. X    break;
  1045. X      case TYPE_THING:
  1046. X    if(pennies < 0 || pennies > MAX_OBJECT_ENDOWMENT) {
  1047. X        printf("Object %s(%d) endowed with %d pennies\n",
  1048. X           db[i].name, i, pennies);
  1049. X    }
  1050. X    break;
  1051. X    }
  1052. X}
  1053. X
  1054. Xvoid main(int argc, char **argv)
  1055. X{
  1056. X    dbref i;
  1057. X
  1058. X    if(db_read(stdin) < 0) {
  1059. X    puts("Database load failed!");
  1060. X    exit(1);
  1061. X    } 
  1062. X
  1063. X    puts("Done loading database");
  1064. X
  1065. X    for(i = 0; i < db_top; i++) {
  1066. X    check_pennies(i);
  1067. X    switch(Typeof(i)) {
  1068. X      case TYPE_PLAYER:
  1069. X        check_contents(i);
  1070. X        check_location(i);
  1071. X        if(Wizard(i)) printf("Wizard: %s(%d)\n", db[i].name, i);
  1072. X        break;
  1073. X      case TYPE_THING:
  1074. X        check_location(i);
  1075. X        break;
  1076. X      case TYPE_ROOM:
  1077. X        check_contents(i);
  1078. X        check_exits(i);
  1079. X        break;
  1080. X    }
  1081. X    }
  1082. X
  1083. X    /* scan for unattached exits */
  1084. X    for(i = 0; i < db_top; i++) {
  1085. X    if(Typeof(i) == TYPE_EXIT) {
  1086. X        printf("Unattached exit %d\n", i);
  1087. X    }
  1088. X    }
  1089. X        
  1090. X    exit(0);
  1091. X}
  1092. END_OF_FILE
  1093. if test 2547 -ne `wc -c <'sanity-check.c'`; then
  1094.     echo shar: \"'sanity-check.c'\" unpacked with wrong size!
  1095. fi
  1096. # end of 'sanity-check.c'
  1097. fi
  1098. if test -f 'small.db.README' -a "${1}" != "-c" ; then 
  1099.   echo shar: Will not clobber existing file \"'small.db.README'\"
  1100. else
  1101. echo shar: Extracting \"'small.db.README'\" \(1371 characters\)
  1102. sed "s/^X//" >'small.db.README' <<'END_OF_FILE'
  1103. XNotes to new administrators using small.db:
  1104. X
  1105. X1. There are four objects of type player in small.db: Wizard(#1),
  1106. XBeaker(#2), guy(#121), and Darooha(#203).  As distributed, all have
  1107. Xthe password "potrzebie."  Wizard is the administrative player; it is
  1108. Xthe only one that has its WIZARD bit set, and it owns most of the core
  1109. Xrooms.  Beaker is included for testing.  guy and Darooha own the
  1110. X"Eastward Ho" and "Bud's" adventures; if you want to leave these
  1111. Xsamples out, you can remove them using extract.  Only the Wizard and
  1112. Xthe objects owned by the Wizard are really important...
  1113. X
  1114. X2. Small.db contains no unlinked exits; thus it will be impossible for
  1115. Xanybody who is not a WIZARD to connect new rooms to the core rooms.
  1116. XWhen TinyMUD was first started up on LANCELOT.AVALON.CS.CMU.EDU, the
  1117. XTown Square was given 9 unlinked exits (7 of the 8 cardinal directions
  1118. Xplus up and down) and was set to be LINK_OK; this allowed early
  1119. Xconstruction to take place in the neighborhood of the Town Square
  1120. Xwithout the need for administrative oversight.  
  1121. X
  1122. XWhile this policy worked well during the early lifetime of the game,
  1123. Xas the database grew the immediate surroundings of the Town Square
  1124. Xbecame rather chaotic, and only a few of the directions exits from it
  1125. Xgot much use.  It might be reasonable to build a more extensive Town
  1126. XCenter before allowing haphazard construction.
  1127. X
  1128. X--Jim Aspnes
  1129. END_OF_FILE
  1130. if test 1371 -ne `wc -c <'small.db.README'`; then
  1131.     echo shar: \"'small.db.README'\" unpacked with wrong size!
  1132. fi
  1133. # end of 'small.db.README'
  1134. fi
  1135. if test -f 'stringutil.c' -a "${1}" != "-c" ; then 
  1136.   echo shar: Will not clobber existing file \"'stringutil.c'\"
  1137. else
  1138. echo shar: Extracting \"'stringutil.c'\" \(868 characters\)
  1139. sed "s/^X//" >'stringutil.c' <<'END_OF_FILE'
  1140. X#include "copyright.h"
  1141. X
  1142. X/* String utilities */
  1143. X
  1144. X#include <ctype.h>
  1145. X
  1146. X#include "externs.h"
  1147. X
  1148. X#define DOWNCASE(x) (isupper(x) ? tolower(x) : (x))
  1149. X
  1150. Xint string_compare(const char *s1, const char *s2)
  1151. X{
  1152. X    while(*s1 && *s2 && DOWNCASE(*s1) == DOWNCASE(*s2)) s1++, s2++;
  1153. X
  1154. X    return(DOWNCASE(*s1) - DOWNCASE(*s2));
  1155. X}
  1156. X
  1157. Xint string_prefix(const char *string, const char *prefix)
  1158. X{
  1159. X    while(*string && *prefix && DOWNCASE(*string) == DOWNCASE(*prefix))
  1160. X    string++, prefix++;
  1161. X    return *prefix == '\0';
  1162. X}
  1163. X
  1164. X/* accepts only nonempty matches starting at the beginning of a word */
  1165. Xconst char *string_match(const char *src, const char *sub)
  1166. X{
  1167. X    if(*sub != '\0') {
  1168. X    while(*src) {
  1169. X        if(string_prefix(src, sub)) return src;
  1170. X        /* else scan to beginning of next word */
  1171. X        while(*src && isalnum(*src)) src++;
  1172. X        while(*src && !isalnum(*src)) src++;
  1173. X    }
  1174. X    }
  1175. X
  1176. X    return 0;
  1177. X}
  1178. X
  1179. END_OF_FILE
  1180. if test 868 -ne `wc -c <'stringutil.c'`; then
  1181.     echo shar: \"'stringutil.c'\" unpacked with wrong size!
  1182. fi
  1183. # end of 'stringutil.c'
  1184. fi
  1185. if test -f 'utils.c' -a "${1}" != "-c" ; then 
  1186.   echo shar: Will not clobber existing file \"'utils.c'\"
  1187. else
  1188. echo shar: Extracting \"'utils.c'\" \(938 characters\)
  1189. sed "s/^X//" >'utils.c' <<'END_OF_FILE'
  1190. X#include "copyright.h"
  1191. X
  1192. X#include "db.h"
  1193. X
  1194. X/* remove the first occurence of what in list headed by first */
  1195. Xdbref remove_first(dbref first, dbref what)
  1196. X{
  1197. X    dbref prev;
  1198. X
  1199. X    /* special case if it's the first one */
  1200. X    if(first == what) {
  1201. X    return db[first].next;
  1202. X    } else {
  1203. X    /* have to find it */
  1204. X    DOLIST(prev, first) {
  1205. X        if(db[prev].next == what) {
  1206. X        db[prev].next = db[what].next;
  1207. X        return first;
  1208. X        }
  1209. X    }
  1210. X    return first;
  1211. X    }
  1212. X}
  1213. X
  1214. Xint member(dbref thing, dbref list)
  1215. X{
  1216. X    DOLIST(list, list) {
  1217. X    if(list == thing) return 1;
  1218. X    }
  1219. X
  1220. X    return 0;
  1221. X}
  1222. X
  1223. Xdbref reverse(dbref list)
  1224. X{
  1225. X    dbref newlist;
  1226. X    dbref rest;
  1227. X
  1228. X    newlist = NOTHING;
  1229. X    while(list != NOTHING) {
  1230. X    rest = db[list].next;
  1231. X    PUSH(list, newlist);
  1232. X    list = rest;
  1233. X    }
  1234. X    return newlist;
  1235. X}
  1236. X
  1237. Xconst char *getname(dbref loc)
  1238. X{
  1239. X    switch(loc) {
  1240. X      case NOTHING:
  1241. X    return "***NOTHING***";
  1242. X      case HOME:
  1243. X    return "***HOME***";
  1244. X      default:
  1245. X    return db[loc].name;
  1246. X    }
  1247. X}
  1248. X
  1249. END_OF_FILE
  1250. if test 938 -ne `wc -c <'utils.c'`; then
  1251.     echo shar: \"'utils.c'\" unpacked with wrong size!
  1252. fi
  1253. # end of 'utils.c'
  1254. fi
  1255. echo shar: End of archive 4 \(of 4\).
  1256. cp /dev/null ark4isdone
  1257. MISSING=""
  1258. for I in 1 2 3 4 ; do
  1259.     if test ! -f ark${I}isdone ; then
  1260.     MISSING="${MISSING} ${I}"
  1261.     fi
  1262. done
  1263. if test "${MISSING}" = "" ; then
  1264.     echo You have unpacked all 4 archives.
  1265.     rm -f ark[1-9]isdone
  1266. else
  1267.     echo You still need to unpack the following archives:
  1268.     echo "        " ${MISSING}
  1269. fi
  1270. ##  End of shell archive.
  1271. exit 0
  1272.